import warnings
warnings.filterwarnings('ignore')
import matplotlib
matplotlib.use('Qt5Agg')

import numpy as np
import matplotlib.pyplot as plt


# 全量梯度下降
X=np.random.rand(100,1)
y = 4 + 5*X + np.random.randn(100,1)
X_new = np.c_[np.ones((100,1)),X]

# 学习率
learning_rate = 0.001
# 迭代次数
n_iterations = 1000
# 初始化
theat  = np.random.randn(2,1)
for i in range(n_iterations):
    #求梯度
    gradients = X_new.T.dot(X_new.dot(theat)-y)
    theat = theat + learning_rate * gradients

print(theat)

# 随机梯度下降
X=2*np.random.randn(100,1)
y = 4+3*X+np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
# 轮次
n_epoch = 1000
theat  = np.random.randn(2,1)
m = 100
learning_rate = 0.001

for epoch in range(n_epoch):
    for j in range(m):
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = xi.T.dot(xi.dot(theat)-yi)
        theat = theat - learning_rate * gradients

print(theat)

# 小批量梯度下降
X=2*np.random.randn(100,1)
y = 4+3*X +np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]

learning_rate = 0.01
n_epochs = 10000
m=100
batch_size=10
num_batches=int(m/batch_size)
theta = np.random.randn(2,1)

for i in range(n_epochs):
    for j in range(num_batches):
        random_index = np.random.randint(m)
        x_batch = X_b[random_index:random_index+batch_size]
        y_batch = y[random_index:random_index+batch_size]
        gradient = x_batch.T.dot(x_batch.dot(theta)-y_batch)
        theta = theta - learning_rate * gradient
print(theta)